package cleandata

import (
	"gitee.com/hexug/go-tools/common/validate"
	"gitee.com/hexug/go-tools/logger"
	"gitee.com/hexug/kube-sync/apps/resource"
	appsv1 "k8s.io/api/apps/v1"
)

var AppName = "cleandata"

type CleanDeploymentRequest struct {
	Deployments map[string][]*appsv1.Deployment `json:"deployments" validate:"required"`
}

func NewCleanDeploymentRequest() *CleanDeploymentRequest {
	return &CleanDeploymentRequest{
		Deployments: make(map[string][]*appsv1.Deployment),
	}
}
func (c *CleanDeploymentRequest) Add(namespace string, deployment *appsv1.Deployment) {
	if _, ok := c.Deployments[namespace]; !ok {
		c.Deployments[namespace] = make([]*appsv1.Deployment, 0)
	}
	c.Deployments[namespace] = append(c.Deployments[namespace], deployment)
}

type DeploymentInfo struct {
	Name      string                 `json:"name"`
	Namespace string                 `json:"namespace"`
	Data      map[string]interface{} `json:"data"`
}

func NewDeploymentInfo(deploymentName string, namespace string, data map[string]interface{}) *DeploymentInfo {
	return &DeploymentInfo{
		Name:      deploymentName,
		Namespace: namespace,
		Data:      data,
	}
}

type CleanDeploymentResponse struct {
	Items map[string][]*DeploymentInfo `json:"items"`
}

func NewCleanDeploymentResponse() *CleanDeploymentResponse {
	return &CleanDeploymentResponse{
		Items: make(map[string][]*DeploymentInfo),
	}
}

func (c *CleanDeploymentResponse) Add(namespace string, deployment []*DeploymentInfo) {
	if _, ok := c.Items[namespace]; !ok {
		c.Items[namespace] = make([]*DeploymentInfo, 0)
	}
	c.Items[namespace] = append(c.Items[namespace], deployment...)
}

type CleanWorkloadInfo struct {
	WorkloadName string                 `json:"workload_name"`
	WorkloadType string                 `json:"workload_type"`
	Namespace    string                 `json:"namespace"`
	Data         map[string]interface{} `json:"data"`
}

func NewCleanWorkloadInfo(wn, namespace, wt string, data map[string]interface{}) *CleanWorkloadInfo {
	return &CleanWorkloadInfo{
		WorkloadName: wn,
		WorkloadType: wt,
		Namespace:    namespace,
		Data:         data,
	}
}

type CleanWorkloadResponse struct {
	Items map[string]*CleanWorkloadInfo `json:"items"`
}

func NewCleanWorkloadResponse() *CleanWorkloadResponse {
	return &CleanWorkloadResponse{
		Items: make(map[string]*CleanWorkloadInfo),
	}
}
func (c *CleanWorkloadResponse) Add(key string, workload *CleanWorkloadInfo) {
	c.Items[key] = workload
}

//type CleanStatefulSetRequest struct {
//}
//
//type CleanStatefulSetResponse struct {
//}
//
//type CleanDaemonSetRequest struct{}
//
//type CleanDaemonSetResponse struct{}
//
//type CleanJobRequest struct{}
//type CleanJobResponse struct{}
//type CleanCronJobRequest struct{}
//type CleanCronJobResponse struct{}

// --------------------------service 部分----------------------

type CleanServiceRequest struct {
	Services []*resource.ListServiceRespone `json:"services" validate:"required"`
}

func NewCleanServiceRequest() *CleanServiceRequest {
	return &CleanServiceRequest{
		Services: make([]*resource.ListServiceRespone, 0),
	}
}

func (c *CleanServiceRequest) Validate() error {
	//if len(c.Services) == 0 {
	//	return fmt.Errorf("service list is empty")
	//}
	return nil
}

func (c *CleanServiceRequest) AddService(service ...*resource.ListServiceRespone) {
	c.Services = append(c.Services, service...)
}

type ServiceInfo struct {
	WorkloadName  string                 `json:"workload_name"`
	Namespace     string                 `json:"namespace"`
	ResourcesKind string                 `json:"resources_kind"`
	Data          map[string]interface{} `json:"data"`
}

func NewServiceInfo(workloadName string, namespace string, data map[string]interface{}) *ServiceInfo {
	return &ServiceInfo{
		WorkloadName:  workloadName,
		Namespace:     namespace,
		ResourcesKind: "Service",
		Data:          data,
	}
}

type CleanServiceResponse struct {
	Items map[string][]*ServiceInfo `json:"items"`
}

func NewCleanServiceResponse() *CleanServiceResponse {
	return &CleanServiceResponse{
		Items: make(map[string][]*ServiceInfo),
	}
}

func (c *CleanServiceResponse) Add(workloadName, namespace, workloadType string, service ...*ServiceInfo) {
	key := namespace + ":" + workloadType + ":" + workloadName
	logger.L().Info("Service key: ", key)
	if _, ok := c.Items[key]; !ok {
		c.Items[key] = make([]*ServiceInfo, 0)
	}
	c.Items[key] = append(c.Items[key], service...)
}

type CleanConfigMapRequest struct {
	ConfigMaps []*resource.ListConfigMapResponse `json:"configmaps" validate:"required"`
}

func NewCleanConfigMapRequest() *CleanConfigMapRequest {
	return &CleanConfigMapRequest{
		ConfigMaps: make([]*resource.ListConfigMapResponse, 0),
	}
}
func (c *CleanConfigMapRequest) AddConfigMap(configMap ...*resource.ListConfigMapResponse) {
	c.ConfigMaps = append(c.ConfigMaps, configMap...)
}
func (c *CleanConfigMapRequest) Validate() error {
	for _, lcmr := range c.ConfigMaps {
		if err := validate.V().Struct(lcmr.ConfigMapCore); err != nil {
			return err
		}
	}
	return nil
}

type ConfigmapInfo struct {
	WorkloadName  string                 `json:"workload_name"`
	Namespace     string                 `json:"namespace"`
	Name          string                 `json:"name"`
	ResourcesKind string                 `json:"resources_kind"`
	Data          map[string]interface{} `json:"data"`
}

func NewConfigmapInfo(workloadName string, namespace string, data map[string]interface{}, name string) *ConfigmapInfo {
	return &ConfigmapInfo{
		WorkloadName:  workloadName,
		Namespace:     namespace,
		Name:          name,
		ResourcesKind: "ConfigMap",
		Data:          data,
	}
}

type CleanConfigMapResponse struct {
	Items map[string][]*ConfigmapInfo `json:"items"`
}

func NewCleanConfigMapResponse() *CleanConfigMapResponse {
	return &CleanConfigMapResponse{
		Items: make(map[string][]*ConfigmapInfo),
	}
}

func (c *CleanConfigMapResponse) Add(workloadName, namespace, workloadType string, service ...*ConfigmapInfo) {
	key := namespace + ":" + workloadType + ":" + workloadName
	logger.L().Info("ConfigMap key: ", key)
	if _, ok := c.Items[key]; !ok {
		c.Items[key] = make([]*ConfigmapInfo, 0)
	}
	c.Items[key] = append(c.Items[key], service...)
}

type RBACCore struct {
	ServiceAccount map[string]interface{}   `json:"service_account"`
	RoleBindings   []map[string]interface{} `json:"role_bindings"`
	ClusterRBs     []map[string]interface{} `json:"cluster_rb"`
	Roles          []map[string]interface{} `json:"roles"`
	ClusterRoles   []map[string]interface{} `json:"cluster_roles"`
}

func NewDefaultRBACCore() *RBACCore {
	return &RBACCore{
		ServiceAccount: make(map[string]interface{}),
		RoleBindings:   make([]map[string]interface{}, 0),
		ClusterRBs:     make([]map[string]interface{}, 0),
		Roles:          make([]map[string]interface{}, 0),
		ClusterRoles:   make([]map[string]interface{}, 0),
	}
}
func (r *RBACCore) AddServiceAccount(serviceAccount map[string]interface{}) {
	r.ServiceAccount = serviceAccount
}
func (r *RBACCore) AddRoleBinding(roleBinding map[string]interface{}) {
	r.RoleBindings = append(r.RoleBindings, roleBinding)
}
func (r *RBACCore) AddClusterRoleBinding(clusterRoleBinding map[string]interface{}) {
	r.ClusterRBs = append(r.ClusterRBs, clusterRoleBinding)
}
func (r *RBACCore) AddRole(role map[string]interface{}) {
	r.Roles = append(r.Roles, role)
}
func (r *RBACCore) AddClusterRole(clusterRole map[string]interface{}) {
	r.ClusterRoles = append(r.ClusterRoles, clusterRole)
}

type CleanRBACResponse struct {
	Items map[string]*RBACCore `json:"items"`
}

func NewCleanRBACResponse() *CleanRBACResponse {
	return &CleanRBACResponse{
		Items: make(map[string]*RBACCore),
	}
}

func (c *CleanRBACResponse) Add(key string, item *RBACCore) {
	c.Items[key] = item
}

type PvPvcCore struct {
	PVs  []map[string]interface{} `json:"pvs"`
	PVCs []map[string]interface{} `json:"pvcs"`
}

func NewDefaultPvPvcCore() *PvPvcCore {
	return &PvPvcCore{
		PVs:  make([]map[string]interface{}, 0),
		PVCs: make([]map[string]interface{}, 0),
	}
}
func (p *PvPvcCore) AddPV(pv map[string]interface{}) {
	p.PVs = append(p.PVs, pv)
}
func (p *PvPvcCore) AddPVC(pvc map[string]interface{}) {
	p.PVCs = append(p.PVCs, pvc)
}

type CleanPvPvcResponse struct {
	Items map[string]*PvPvcCore `json:"items"`
}

func NewCleanPvPvcResponse() *CleanPvPvcResponse {
	return &CleanPvPvcResponse{
		Items: make(map[string]*PvPvcCore),
	}
}
func (c *CleanPvPvcResponse) Add(key string, item *PvPvcCore) {
	c.Items[key] = item
}

type SecretCore struct {
	ResourcesKind string                   `json:"resources_kind"`
	Namespace     string                   `json:"namespace"`
	Secrets       []map[string]interface{} `json:"secrets"`
}

func NewDefaultSecretCore(ns string) *SecretCore {
	return &SecretCore{
		Secrets:       make([]map[string]interface{}, 0),
		ResourcesKind: "Secret",
		Namespace:     ns,
	}
}
func (s *SecretCore) AddSecret(secret map[string]interface{}) {
	s.Secrets = append(s.Secrets, secret)
}

type CleanSecretResponse struct {
	Items map[string]*SecretCore `json:"items"`
}

func NewCleanSecretResponse() *CleanSecretResponse {
	return &CleanSecretResponse{
		Items: make(map[string]*SecretCore),
	}
}
func (c *CleanSecretResponse) Add(key string, item *SecretCore) {
	c.Items[key] = item
}
